﻿#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <map>
#include <functional>
using namespace std;


void swap_func(int& r1, int& r2) {
	int tmp = r1;
	r1 = r2;
	r2 = tmp;
}

struct Swap {
	void operator()(int& r1, int& r2) {
		int tmp = r1;
		r1 = r2;
		r2 = tmp;
	}
};

//// 包装函数名(函数指针)\函数、函数对象、lamber表达式
//int main() {
//	int x = 0, y = 1;
//	cout << x << " " << y << endl;
//	auto swaplambda = [](int& r1, int& r2) {
//		int tmp = r1;
//		r1 = r2;
//		r2 = tmp;
//	};
//
//	//function<void(int&, int&)> f1(swap_func);
//	function<void(int&, int&)> f1 = swap_func;
//	f1(x, y);
//	cout << x << " " << y << endl;
//
//	function<void(int&, int&)> f2 = Swap();
//	f2(x, y);
//	cout << x << " " << y << endl;
//
//	function<void(int&, int&)> f3 = swaplambda;
//	f3(x, y);
//	cout << x << " " << y << endl;
//
//	map<string, function<void(int&, int&)>> cmdOP = { {"函数指针",swap_func},{"仿函数",Swap()}, {"lambda",swaplambda} };
//	cmdOP["函数指针"](x, y);
//	cout << x << " " << y << endl;
//	cmdOP["仿函数"](x, y);
//	cout << x << " " << y << endl;
//	cmdOP["lambda"](x, y);
//	cout << x << " " << y << endl;
//	return 0;
//}



//包装类的成员函数
int f(int a, int b) { return a + b; }

struct Functor {
public:
	int operator() (int a, int b) { return a + b; }
};

class Plus {
public:
	static int plusi(int a, int b) { return a + b; }
	double plusd(double a, double b) { return a + b; }
};

int main() {
	//成员函数取地址要加&和类域，虽然静态成员函数不用&，但建议加上
	function<int(int, int)> f1 = &Plus::plusi;
	cout << f1(1, 2) << endl;

	////成员函数参数中还有this指针，所以不匹配
	//function<double(double, double)> f2 = &Plus::plusd;

	function<double(Plus*, double, double)> f2 = &Plus::plusd;
	Plus ps;
	cout << f2(&ps, 1.1, 2.2) << endl;
	//cout << f2(&Plus(), 1.1, 2.2) << endl;//不可以传匿名对象(是右值)，左值才能取地址

	//特殊处理，相当于用对象调函数
	function<double(Plus, double, double)> f3 = &Plus::plusd;
	cout << f3(Plus(), 1.1, 2.2) << endl;

	//使用bind绑定第一个参数
	function<double(double, double)> f4 = bind(&Plus::plusd, Plus(), placeholders::_1, placeholders::_2);
	cout << f4(1.1, 2.2) << endl;
	return 0;
}



////演示bind用法
//int Sub(int a, int b) { return a - b; }
//
//int main() {
//	function<int(int, int)> f1 = Sub;
//	cout << f1(10, 5) << endl;//5
//
//	//调整参数的顺序
//	function<int(int, int)> f2 = bind(Sub, placeholders::_2, placeholders::_1);
//	cout << f2(10, 5) << endl;//-5
//
//	//调整参数的个数，有些参数可以bind时写死。20固定是第一个
//	function<int(int)> f3 = bind(Sub, 20, placeholders::_1);
//	cout << f3(5) << endl;//15
//	return 0;
//}